<template>
  <div class="project-wayline-wrapper height-100">
    <a-spin :spinning="loading" :delay="300" tip="downloading" size="large">
    <div style="height: 50px; line-height: 50px; border-bottom: 1px solid #4f4f4f; font-weight: 450;">
      <a-row>
        <a-col :span="1"></a-col>
        <a-col :span="15">Flight Route Library</a-col>
        <a-col :span="5" class="flex-row flex-justify-end flex-align-center">
            <a-button type="text" @click="openPlan" style="color: white;">
              <PlusOutlined />
            </a-button>
        </a-col>
        <a-col :span="3" v-if="importVisible" class="flex-row flex-justify-end flex-align-center">
          <a-upload
            name="file"
            :multiple="false"
            :before-upload="beforeUpload"
            :show-upload-list="false"
            :customRequest="uploadFile"
          >
            <a-button type="text" style="color: white;">
              <SelectOutlined />
            </a-button>
          </a-upload>
        </a-col>
      </a-row>
    </div>
    <div class="create-plan-wrapper" v-if="drawerVisible">
      <div class="header">
        Create Flight Route
      </div>
      <div class="content">
        <a-form ref="valueRef" layout="horizontal" :hideRequiredMark="true" :rules="rules" :model="planBody" labelAlign="left">
          <!-- name -->
          <a-form-item label="Flight Route Name" name="name" :labelCol="{span: 23}">
            <a-input style="background: black;"  placeholder="Please enter flight route name" v-model:value="planBody.name"/>
          </a-form-item>
          <!-- style -->
          <a-form-item label="航线类型" name="style" :labelCol="{span: 23}">
            <a-radio-group v-model:value="planBody.style">
              <a-radio value="1">航点飞行</a-radio>
              <a-radio value="2">航带飞行</a-radio>
              <a-radio value="3">建图航拍</a-radio>
              <a-radio value="4">贴近摄影</a-radio>
            </a-radio-group>
          </a-form-item>
          <!-- height -->
          <a-form-item label="Minimum flight height (m)" name="minheight" :labelCol="{span: 23} " v-if="planBody.style == '4'">
            <a-input style="background: black;"  placeholder="Please enter minimum flight height" v-model:value="planBody.minheight"/>
          </a-form-item>
          <a-form-item label="Flight height (m)" name="height" :labelCol="{span: 23}" v-if="planBody.style !== '4'">
            <a-input style="background: black;"  placeholder="Please enter flight height" v-model:value="planBody.height"/>
          </a-form-item>
          <!-- distance -->
          <a-form-item label="Distance (m)" name="distance" :labelCol="{span: 23}" v-if="planBody.style == '4'">
            <a-input style="background: black;"  placeholder="Please enter distance" v-model:value="planBody.distance"/>
          </a-form-item>
          <!-- speed -->
          <a-form-item label="Flight speed (m/s)" name="speed" :labelCol="{span: 23}">
            <a-input style="background: black;"  placeholder="Please enter flight speed" v-model:value="planBody.speed"/>
          </a-form-item>
          <!-- hxcdl -->
          <a-form-item label="航向重叠率 (%)" name="hxcdl" :labelCol="{span: 23}">
            <a-input style="background: black;"  placeholder="Please enter 航向重叠率" v-model:value="planBody.hxcdl"/>
          </a-form-item>
          <!-- pxcdl -->
          <a-form-item label="旁向重叠率 (%)" name="pxcdl" :labelCol="{span: 23}">
            <a-input style="background: black;"  placeholder="Please enter 旁向重叠率" v-model:value="planBody.pxcdl"/>
          </a-form-item>
          <!-- Building height -->
          <a-form-item label="Building height (m)" name="buildingheight" :labelCol="{span: 23}" v-if="planBody.style == '4'">
            <a-input style="background: black;"  placeholder="Please enter building height" v-model:value="planBody.buildingheight"/>
          </a-form-item>
          <!-- Building height -->
          <a-form-item >
            <a-button class="mr10" style="background: #fff;"  @click="draw">Selection range
            </a-button>
            <a-button type="primary" @click="draw('off', false)" :disabled="disabled">OK
            </a-button>
          </a-form-item>
          <!-- cancel or onsubmit -->
          <a-form-item class="width-100" style="margin-bottom: 40px;">
            <div class="footer">
              <a-button class="mr10" style="background: #3c3c3c;" @click="closePlan">Cancel
              </a-button>
              <a-button class="mr10" style="background: #3c3c3c;" @click="onSubmit" :disabled="disabled">Check
              </a-button>
              <a-button type="primary" @click="onSubmit" :disabled="disabled">Submit
              </a-button>
            </div>
          </a-form-item>
        </a-form>
      </div>
    </div>
    <div :style="{ height : height + 'px'}" class="scrollbar">
      <div id="data" class="height-100 uranus-scrollbar" v-if="waylinesData.data.length !== 0" @scroll="onScroll">
        <div v-for="wayline in waylinesData.data" :key="wayline.id">
          <div class="wayline-panel" style="padding-top: 5px;" @click="selectRoute(wayline)">
            <div class="title">
              <a-tooltip :title="wayline.name">
                <div class="pr10" style="width: 120px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;">{{ wayline.name }}</div>
              </a-tooltip>
              <div class="ml10"><UserOutlined /></div>
              <a-tooltip :title="wayline.user_name">
                <div class="ml5 pr10" style="width: 80px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;">{{ wayline.user_name }}</div>
              </a-tooltip>
              <div class="fz20">
                <a-dropdown>
                  <a style="color: white;">
                    <EllipsisOutlined />
                  </a>
                  <template #overlay>
                    <a-menu theme="dark" class="more" style="background: #3c3c3c;">
                      <a-menu-item @click="downloadWayline(wayline.id, wayline.name)">
                        <span>Download</span>
                      </a-menu-item>
                      <a-menu-item @click="showWaylineTip(wayline.id)">
                        <span>Delete</span>
                      </a-menu-item>
                    </a-menu>
                  </template>
                </a-dropdown>
              </div>
            </div>
            <div class="ml10 mt5" style="color: hsla(0,0%,100%,0.65);">
              <span><RocketOutlined /></span>
              <span class="ml5">{{ DEVICE_NAME[wayline.drone_model_key] }}</span>
              <span class="ml10"><CameraFilled style="border-top: 1px solid; padding-top: -3px;" /></span>
              <span class="ml5" v-for="payload in wayline.payload_model_keys" :key="payload.id">
                {{ DEVICE_NAME[payload] }}
              </span>
            </div>
            <div class="mt5 ml10" style="color: hsla(0,0%,100%,0.35);">
              <span class="mr10">Update at {{ new Date(wayline.update_time).toLocaleString() }}</span>
            </div>
          </div>
        </div>
      </div>
      <div v-else>
        <a-empty :image-style="{ height: '60px', marginTop: '60px' }" />
      </div>
      <a-modal v-model:visible="deleteTip" width="450px" :closable="false" :maskClosable="false" centered :okButtonProps="{ danger: true }" @ok="deleteWayline">
          <p class="pt10 pl20" style="height: 50px;">Wayline file is unrecoverable once deleted. Continue?</p>
          <template #title>
              <div class="flex-row flex-justify-center">
                  <span>Delete</span>
              </div>
          </template>
      </a-modal>
    </div>
    </a-spin>
  </div>
</template>

<script lang="ts" setup>
import { reactive } from '@vue/reactivity'
import { message } from 'ant-design-vue'
import { computed, onMounted, onUpdated, ref } from 'vue'
import { deleteWaylineFile, downloadWaylineFile, getWaylineFiles, importKmzFile } from '/@/api/wayline'
import { ELocalStorageKey, ERouterName } from '/@/types'
import { EllipsisOutlined, RocketOutlined, CameraFilled, UserOutlined, SelectOutlined, PlusOutlined } from '@ant-design/icons-vue'
import { DEVICE_NAME } from '/@/types/device'
import { useMyStore } from '/@/store'
import { WaylineFile } from '/@/types/wayline'
import { downloadFile } from '/@/utils/common'
import { IPage } from '/@/api/http/type'
import { CURRENT_CONFIG } from '/@/api/http/config'
import { load } from '@amap/amap-jsapi-loader'
import { getRoot } from '/@/root'

import { MapDoodleType, MapElementEnum } from '/@/constants/map'
import { EFlightAreaType } from '/@/types/flight-area'
import { MapDoodleEnum } from '/@/types/map-enum'
import { useMouseTool } from '/@/hooks/use-mouse-tool'
import { useFlightArea } from '/@/components/flight-area/use-flight-area'
import { useFlightAreaDroneLocationEvent } from '/@/components/flight-area/use-flight-area-drone-location-event'
import { postElementsReq } from '/@/api/layer'
import { generatePolyContent } from '/@/utils/map-layer-utils'
import { uuidv4 } from '/@/utils/uuid'
import { PostElementsBody } from '/@/types/mapLayer'
import { GeojsonCoordinate } from '/@/types/map'
import { gcj02towgs84, wgs84togcj02 } from '/@/vendors/coordtransform'

const loading = ref(false)
const store = useMyStore()
const pagination :IPage = {
  page: 1,
  total: -1,
  page_size: 10
}

const waylinesData = reactive({
  data: [] as WaylineFile[]
})

const root = getRoot()
const workspaceId = localStorage.getItem(ELocalStorageKey.WorkspaceId)!
const deleteTip = ref(false)
const deleteWaylineId = ref<string>('')
const canRefresh = ref(true)
const importVisible = ref<boolean>(root.$router.currentRoute.value.name === ERouterName.WAYLINE)
const height = ref()
const rules = {
  name: [
    { required: true, message: 'Please enter plan name.' },
    { max: 20, message: 'Length should be 1 to 20' }
  ],
  style: [{ required: true, message: 'Please enter flight style.' }],
  speed: [{ required: true, message: 'Please enter flight height.' }],
  hxcdl: [{ required: true, message: 'Please enter flight height.' }],
  pxcdl: [{ required: true, message: 'Please enter flight height.' }],
  file_id: [{ required: true, message: 'Select Route' }],
  dock_sn: [{ required: true, message: 'Select Device' }],
}

const planBody = reactive({
  name: '',
  style: '',
  height: '',
  minheight: '',
  distance: '',
  speed: '',
  pxcdl: '',
  hxcdl: '',
  buildingheight: ''
})

const disabled = ref(false)
const drawerVisible = ref(false)
const mouseMode = ref(false)
const useMouseToolHook = useMouseTool()
const state = reactive({
  currentType: '',
  coverIndex: 0,
  isFlightArea: false,
})
const { getDrawFlightAreaCallback, onFlightAreaDroneLocationWs } = useFlightArea()
useFlightAreaDroneLocationEvent(onFlightAreaDroneLocationWs)
const shareId = computed(() => {
  return store.state.layerBaseInfo.share
})

onMounted(() => {
  const parent = document.getElementsByClassName('scrollbar').item(0)?.parentNode as HTMLDivElement
  height.value = document.body.clientHeight - parent.firstElementChild!.clientHeight
  getWaylines()

  const key = setInterval(() => {
    const data = document.getElementById('data')?.lastElementChild as HTMLDivElement
    if (pagination.total === 0 || Math.ceil(pagination.total / pagination.page_size) <= pagination.page || height.value <= data?.clientHeight + data?.offsetTop) {
      clearInterval(key)
      return
    }
    pagination.page++
    getWaylines()
  }, 1000)
})

function getWaylines () {
  if (!canRefresh.value) {
    return
  }
  canRefresh.value = false
  getWaylineFiles(workspaceId, {
    page: pagination.page,
    page_size: pagination.page_size,
    order_by: 'update_time desc'
  }).then(res => {
    if (res.code !== 0) {
      return
    }
    waylinesData.data = [...waylinesData.data, ...res.data.list]
    pagination.total = res.data.pagination.total
    pagination.page = res.data.pagination.page
  }).finally(() => {
    canRefresh.value = true
  })
}

function showWaylineTip (waylineId: string) {
  deleteWaylineId.value = waylineId
  deleteTip.value = true
}

function deleteWayline () {
  deleteWaylineFile(workspaceId, deleteWaylineId.value).then(res => {
    if (res.code === 0) {
      message.success('Wayline file deleted')
    }
    deleteWaylineId.value = ''
    deleteTip.value = false
    pagination.total = 0
    pagination.page = 1
    waylinesData.data = []
    getWaylines()
  })
}

function downloadWayline (waylineId: string, fileName: string) {
  loading.value = true
  downloadWaylineFile(workspaceId, waylineId).then(res => {
    if (!res) {
      return
    }
    const data = new Blob([res], { type: 'application/zip' })
    downloadFile(data, fileName + '.kmz')
  }).finally(() => {
    loading.value = false
  })
}

function selectRoute (wayline: WaylineFile) {
  store.commit('SET_SELECT_WAYLINE_INFO', wayline)
}

function onScroll (e: any) {
  const element = e.srcElement
  if (element.scrollTop + element.clientHeight >= element.scrollHeight - 5 && Math.ceil(pagination.total / pagination.page_size) > pagination.page && canRefresh.value) {
    pagination.page++
    getWaylines()
  }
}

function openPlan () {
  drawerVisible.value = true
}

function closePlan () {
  drawerVisible.value = false
}

function draw (type: MapDoodleType, bool: boolean, flightAreaType?: EFlightAreaType) {
  state.currentType = type
  mouseMode.value = bool
  state.isFlightArea = !!flightAreaType
  useMouseToolHook.mouseTool(type, getDrawCallback, flightAreaType)
}

function getDrawCallback ({ obj }: { obj : any }) {
  if (state.isFlightArea) {
    getDrawFlightAreaCallback(obj)
    return
  }
  switch (state.currentType) {
    case MapDoodleEnum.POLYGON:
      postPolygonResource(obj)
      break
    default:
      break
  }
}

async function postPolygonResource (obj) {
  const req = getPoygonResource(obj)
  setLayers(req)
  updateCoordinates('gcj02-wgs84', req)
  const result = await postElementsReq(shareId.value, req)
  obj.setExtData({ id: req.id, name: req.name })
  store.state.coverMap[req.id] = [obj]
}
function getPoygonResource (obj) {
  const path = obj.getPath()
  const resource = generatePolyContent(path)
  const { name, id } = getBaseInfo(obj._opts)
  return {
    id,
    name,
    resource
  }
}
function getBaseInfo (obj) {
  const name = obj.title
  const id = uuidv4()
  return { name, id }
}
function setLayers (resource: PostElementsBody) {
  const layers = store.state.Layers
  const layer = layers.find(item => item.id.includes(shareId.value))
  // layer.id = 'private_layer' + uuidv4()
  // layer?.elements.push(resource)
  if (layer?.elements) {
    ;(layer?.elements as any[]).push(resource)
  }
  console.log('layers', layers)
  store.commit('SET_LAYER_INFO', layers)
}
function updateCoordinates (transformType: string, element: any) {
  const geoType = element.resource?.content.geometry.type
  const type = element.resource?.type as number
  if (element.resource) {
    if (MapElementEnum.PIN === type) {
      const coordinates = element.resource?.content.geometry
        .coordinates as GeojsonCoordinate
      if (transformType === 'wgs84-gcj02') {
        const transResult = wgs84togcj02(
          coordinates[0],
          coordinates[1]
        ) as GeojsonCoordinate
        element.resource.content.geometry.coordinates = transResult
      } else if (transformType === 'gcj02-wgs84') {
        const transResult = gcj02towgs84(
          coordinates[0],
          coordinates[1]
        ) as GeojsonCoordinate
        element.resource.content.geometry.coordinates = transResult
      }
    } else if (MapElementEnum.LINE === type) {
      const coordinates = element.resource?.content.geometry
        .coordinates as GeojsonCoordinate[]
      if (transformType === 'wgs84-gcj02') {
        coordinates.forEach((coordinate, i, arr) => {
          arr[i] = wgs84togcj02(
            coordinate[0],
            coordinate[1]
          ) as GeojsonCoordinate
        })
      } else if (transformType === 'gcj02-wgs84') {
        coordinates.forEach((coordinate, i, arr) => {
          arr[i] = gcj02towgs84(
            coordinate[0],
            coordinate[1]
          ) as GeojsonCoordinate
        })
      }
      element.resource.content.geometry.coordinates = coordinates
    } else if (MapElementEnum.POLY === type) {
      const coordinates = element.resource?.content.geometry
        .coordinates[0] as GeojsonCoordinate[]
      if (transformType === 'wgs84-gcj02') {
        coordinates.forEach((coordinate, i, arr) => {
          arr[i] = wgs84togcj02(
            coordinate[0],
            coordinate[1]
          ) as GeojsonCoordinate
        })
      } else if (transformType === 'gcj02-wgs84') {
        coordinates.forEach((coordinate, i, arr) => {
          arr[i] = gcj02towgs84(
            coordinate[0],
            coordinate[1]
          ) as GeojsonCoordinate
        })
      }
      element.resource.content.geometry.coordinates = [coordinates]
    }
  }
}

function onSubmit () {}

interface FileItem {
  uid: string;
  name?: string;
  status?: string;
  response?: string;
  url?: string;
}

interface FileInfo {
  file: FileItem;
  fileList: FileItem[];
}
const fileList = ref<FileItem[]>([])

function beforeUpload (file: FileItem) {
  fileList.value = [file]
  loading.value = true
  return true
}
const uploadFile = async () => {
  fileList.value.forEach(async (file: FileItem) => {
    const fileData = new FormData()
    fileData.append('file', file, file.name)
    await importKmzFile(workspaceId, fileData).then((res) => {
      if (res.code === 0) {
        message.success(`${file.name} file uploaded successfully`)
        canRefresh.value = true
        pagination.total = 0
        pagination.page = 1
        waylinesData.data = []
        getWaylines()
      }
    }).finally(() => {
      loading.value = false
      fileList.value = []
    })
  })
}

</script>

<style lang="scss" scoped>
.wayline-panel {
  background: #3c3c3c;
  margin-left: auto;
  margin-right: auto;
  margin-top: 10px;
  height: 90px;
  width: 95%;
  font-size: 13px;
  border-radius: 2px;
  cursor: pointer;
  .title {
    display: flex;
    flex-direction: row;
    align-items: center;
    height: 30px;
    font-weight: bold;
    margin: 0px 10px 0 10px;
  }
}
.uranus-scrollbar {
  overflow: auto;
  scrollbar-width: thin;
  scrollbar-color: #c5c8cc transparent;
}
.create-plan-wrapper {
  background-color: #232323;
  color: fff;
  padding-bottom: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  width: 285px;

  .header {
    height: 52px;
    border-bottom: 1px solid #4f4f4f;
    font-weight: 700;
    font-size: 16px;
    padding-left: 10px;
    display: flex;
    align-items: center;
  }

  ::-webkit-scrollbar {
    display: none;
  }

  .content {
    height: calc(100% - 54px);
    overflow-y: auto;

    form {
      margin: 10px;
    }

    form label, input, .ant-input, .ant-calendar-range-picker-separator,
    .ant-input:hover, .ant-time-picker .anticon, .ant-calendar-picker .anticon {
      background-color: #232323;
      color: #fff;
    }

    .ant-input-suffix {
      color: #fff;
    }

    .plan-timer-form-item {

      .ant-radio-button-wrapper{
        background-color: #232323;
        color: #fff;
        width: 33%;
        text-align: center;
        &.ant-radio-button-wrapper-checked{
          background-color: #1890ff;
        }
      }
    }
  }

  .footer {
    display: flex;
    padding:10px 0;

    button {
      width: 45%;
      color: #fff ;
      border: 0;
    }
  }
}
</style>
